#include <wx/string.h>
#include <wx/file.h>
#include "crc32.h"
#include "globals.h"

static wxUint32 *GetCRC32Table( wxUint32 *crc_table ) {
  if( !crc_table ) {
    crc_table = new wxUint32[256];
    if( crc_table ) {
      for( unsigned int i = 0; i < 256; ++i ) {
        wxUint32 crc = i;
        for( unsigned int j = 8; j > 0; --j ) {
          if( crc & 1 ) {
            crc = ( crc >> 1 ) ^ 0xEDB88320UL;
          } else
          { crc >>= 1; }
        }
        crc_table[i] = crc;
      }
    }
  }
  return ( crc_table ) ;
}

wxUint32 wxCrc32::FromFile( const wxString& file ) {
  wxFile f( file );
  wxString contents = cbReadFileContents( f );
  if( contents.IsEmpty() ) {
    return 0;
  }
  return FromString( contents );
}

wxUint32 wxCrc32::FromString( const wxString& text ) {
  static wxUint32 *crc_table = NULL;
  wxUint32 crc = 0;
  unsigned int i = 0;
  if( !text.IsEmpty() ) {
    crc_table = GetCRC32Table( crc_table ) ;
    if( crc_table ) {
      crc = 0xFFFFFFFFUL;
      while( text[i] ) {
        crc = ( crc >> 8 ) ^ crc_table[( crc ^ ( text[i++] ) ) & 0xFF ];
      }
      crc ^= 0xFFFFFFFFUL ;
    }
  }
  if( crc_table ) {
    delete[] crc_table;
  }
  crc_table = NULL;
  return( crc ) ;
}
